package io.aicn.lowcode.service.dbmanager.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.aicn.lowcode.entity.dbmanager.DataSource;
import io.aicn.lowcode.mapper.dbmanager.DataSourceMapper;
import io.aicn.lowcode.service.dbmanager.IDataSourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 数据源配置Service实现类
 * 
 * @author lowcode-generator
 * @since 2025-01-25
 */
@Slf4j
@Service
public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSource> implements IDataSourceService {

    @Override
    public boolean testConnection(DataSource dataSource) {
        try {
            String url = buildJdbcUrl(dataSource);
            Class.forName(getDriverClassName(dataSource.getType()));
            
            try (Connection connection = DriverManager.getConnection(url, dataSource.getUsername(), dataSource.getPassword())) {
                return connection.isValid(5); // 5秒超时
            }
        } catch (Exception e) {
            log.error("数据源连接测试失败: {}", e.getMessage());
            return false;
        }
    }

    @Override
    public List<DataSource> listByStatus(String status) {
        return baseMapper.selectByStatus(status);
    }

    @Override
    public List<DataSource> listByType(String type) {
        return baseMapper.selectByType(type);
    }

    @Override
    public List<DataSource> listByNameLike(String name) {
        return baseMapper.selectByNameLike(name);
    }

    @Override
    public boolean existsByName(String name, Long excludeId) {
        if (excludeId == null) {
            excludeId = -1L;
        }
        return baseMapper.countByNameExcludeId(name, excludeId) > 0;
    }

    @Override
    public DataSource createWithTest(DataSource dataSource) {
        // 检查名称是否重复
        if (existsByName(dataSource.getName(), null)) {
            throw new RuntimeException("数据源名称已存在: " + dataSource.getName());
        }

        // 测试连接
        boolean connected = testConnection(dataSource);
        dataSource.setStatus(connected ? DataSource.Status.CONNECTED.getCode() : DataSource.Status.DISCONNECTED.getCode());
        
        // 设置创建时间
        dataSource.setCreateTime(LocalDateTime.now());
        dataSource.setUpdateTime(LocalDateTime.now());
        
        // 保存数据源
        save(dataSource);
        
        return dataSource;
    }

    @Override
    public boolean updateStatus(Long id, String status) {
        DataSource dataSource = getById(id);
        if (dataSource == null) {
            return false;
        }
        
        dataSource.setStatus(status);
        dataSource.setUpdateTime(LocalDateTime.now());
        
        return updateById(dataSource);
    }

    @Override
    public String refreshAllStatus() {
        List<DataSource> dataSources = list();
        int total = dataSources.size();
        int connected = 0;
        int disconnected = 0;
        
        for (DataSource dataSource : dataSources) {
            boolean isConnected = testConnection(dataSource);
            String newStatus = isConnected ? DataSource.Status.CONNECTED.getCode() : DataSource.Status.DISCONNECTED.getCode();
            
            if (isConnected) {
                connected++;
            } else {
                disconnected++;
            }
            
            updateStatus(dataSource.getId(), newStatus);
        }
        
        return String.format("刷新完成: 总计%d个数据源，连接成功%d个，连接失败%d个", total, connected, disconnected);
    }

    @Override
    public List<DataSource> listWithoutConfig() {
        return baseMapper.selectAllWithoutConfig();
    }

    /**
     * 构建JDBC连接URL
     */
    private String buildJdbcUrl(DataSource dataSource) {
        String baseUrl = String.format("jdbc:%s://%s:%d/%s", 
            dataSource.getType(), 
            dataSource.getHost(), 
            dataSource.getPort(), 
            dataSource.getDatabaseName());
        
        // 添加默认参数
        if ("mysql".equals(dataSource.getType())) {
            baseUrl += "?useUnicode=true&characterEncoding=UTF-8&useSSL=true&serverTimezone=UTC";
        }
        
        return baseUrl;
    }

    /**
     * 获取驱动类名
     */
    private String getDriverClassName(String type) {
        switch (type.toLowerCase()) {
            case "mysql":
                return "com.mysql.cj.jdbc.Driver";
            case "postgresql":
                return "org.postgresql.Driver";
            default:
                throw new RuntimeException("不支持的数据库类型: " + type);
        }
    }
}